{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 跟踪车辆x与y\n",
    "\n",
    "既然你已经知道如何解决三角函数问题，那么你可以跟踪车辆 $x$ 与 $y$ 在任何方向上的移动信息。\n",
    "\n",
    "本节课的目的是让你在`Vehicle` 类中实现一些方法。 完成后，你的代码就可以像这样运行了："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'Vehicle' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-1-8416ccde0880>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[0;31m# instantiate vehicle\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mv\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mVehicle\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      3\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      4\u001b[0m \u001b[0;31m# drive forward 10 meters\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      5\u001b[0m \u001b[0mv\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdrive_forward\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m10\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mNameError\u001b[0m: name 'Vehicle' is not defined"
     ]
    }
   ],
   "source": [
    "# instantiate vehicle\n",
    "v = Vehicle()\n",
    "\n",
    "# drive forward 10 meters\n",
    "v.drive_forward(10)\n",
    "\n",
    "# turn left in 10 increments of 9 degrees each.\n",
    "for _ in range(10):\n",
    "    v.turn(9.0)\n",
    "    v.drive_forward(1)\n",
    "\n",
    "v.drive_forward(10)\n",
    "\n",
    "v.show_trajectory()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "并且最后调用`show_trajectory` ，应该会产生如下所示的图形：\n",
    "\n",
    "![](https://d17h27t6h515a5.cloudfront.net/topher/2017/December/5a3184b7_xy-traj/xy-traj.png)\n",
    "\n",
    "如果，我们没有调用它"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'v' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-2-e59105099756>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mv\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshow_trajectory\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m: name 'v' is not defined"
     ]
    }
   ],
   "source": [
    "v.show_trajectory()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "而是这样写道："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'v' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-3-33737b0684a2>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mv\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mhistory\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m: name 'v' is not defined"
     ]
    }
   ],
   "source": [
    "print(v.history)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "我们就会看到代表车辆历史数据的`(x,y)`元组列表，如下所示："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[(0.0, 0.0),\n",
       " (10.0, 0.0),\n",
       " (10.988, 0.156),\n",
       " (11.939, 0.465),\n",
       " (12.83, 0.919),\n",
       " (13.639, 1.507),\n",
       " (14.346, 2.214),\n",
       " (14.934, 3.023),\n",
       " (15.388, 3.914),\n",
       " (15.697, 4.865),\n",
       " (15.853, 5.853),\n",
       " (15.853, 6.853)]"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "[(0.0, 0.0),\n",
    " (10.0, 0.0),\n",
    " (10.988, 0.156),\n",
    " (11.939, 0.465),\n",
    " (12.830, 0.919),\n",
    " (13.639, 1.507),\n",
    " (14.346, 2.214),\n",
    " (14.934, 3.023),\n",
    " (15.388, 3.914),\n",
    " (15.697, 4.865),\n",
    " (15.853, 5.853),\n",
    " (15.853, 6.853)]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "请注意，这是用于将`show_trajectory`中的点的`history` 数据绘制成图。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "from math import sin, cos, pi\n",
    "from matplotlib import pyplot as plt\n",
    "\n",
    "# TODO - Complete the methods in the vehicle class. If the \n",
    "#        requirements of any method are unclear, look at \n",
    "#        the testing code in testing.py (you'll need to\n",
    "#        click on the \"Jupyter\" logo in the top left and\n",
    "#        then open testing.py)\n",
    "#\n",
    "#        If you really get stuck, take a look at the \n",
    "#        solution code in the next segment.\n",
    "\n",
    "class Vehicle:\n",
    "    def __init__(self):\n",
    "        self.x       = 0.0 # meters\n",
    "        self.y       = 0.0\n",
    "        self.heading = 0.0 # radians\n",
    "        self.history = []\n",
    "        \n",
    "    def drive_forward(self, displacement):\n",
    "        \"\"\"\n",
    "        Updates x and y coordinates of vehicle based on \n",
    "        heading and appends previous (x,y) position to\n",
    "        history.\n",
    "        \"\"\"\n",
    "        pass\n",
    "    \n",
    "    def set_heading(self, heading_in_degrees):\n",
    "        \"\"\"\n",
    "        Sets the current heading (in radians) to a new value\n",
    "        based on heading_in_degrees. Vehicle heading is always\n",
    "        between 0 and 2 * pi.\n",
    "        \"\"\"\n",
    "        pass\n",
    "    \n",
    "    def turn(self, angle_in_degrees):\n",
    "        \"\"\"\n",
    "        Changes the vehicle's heading by angle_in_degrees. Vehicle \n",
    "        heading is always between 0 and 2 * pi.\n",
    "        \"\"\"\n",
    "        pass\n",
    "    \n",
    "    def show_trajectory(self):\n",
    "        \"\"\"\n",
    "        Creates a scatter plot of vehicle's trajectory.\n",
    "        \"\"\"\n",
    "        pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Error\n",
      "After calling set_heading(90), heading was not pi/2\n",
      "Instead, heading was 0.0\n",
      "Error\n",
      "When vehicle's heading is 0, a motion of 10\n",
      "Should move the vehicle forward 10 in the x direction\n"
     ]
    }
   ],
   "source": [
    "# Use this testing code to check your code for correctness.\n",
    "from testing import test_drive_forward, test_set_heading\n",
    "\n",
    "test_set_heading(Vehicle)\n",
    "test_drive_forward(Vehicle)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "# You'll have to \"test\" your show_trajectory method \n",
    "# visually. Run the code below and see if the plot that's\n",
    "# produced looks similar to the plot at the bottom of \n",
    "# this notebook.\n",
    "\n",
    "# instantiate vehicle\n",
    "v = Vehicle()\n",
    "\n",
    "# drive forward 10 meters\n",
    "v.drive_forward(10)\n",
    "\n",
    "# turn left in 10 increments of 9 degrees each.\n",
    "for _ in range(10):\n",
    "    v.turn(9.0)\n",
    "    v.drive_forward(1)\n",
    "\n",
    "v.drive_forward(10)\n",
    "\n",
    "v.show_trajectory()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "解决方案代码中的参考图如下：\n",
    "![](https://d17h27t6h515a5.cloudfront.net/topher/2017/December/5a3184b7_xy-traj/xy-traj.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
